package com.uqbar.pacman.components;

import java.awt.Color;
import java.awt.image.BufferedImage;
import java.util.ArrayList;

import javax.imageio.ImageIO;


import com.uqbar.pacman.scenes.PacmanScene;
import com.uqbar.vainilla.DeltaState;
import com.uqbar.vainilla.GameComponent;
import com.uqbar.vainilla.appearances.Circle;
import com.uqbar.vainilla.colissions.CollisionDetector;
import com.uqbar.vainilla.events.constants.Key;
import com.uqbar.vainilla.exceptions.GameException;

public class Pacman extends GameComponent<PacmanScene> {
	private int speed;
	private int xMin, yMin=0;
	private int xMax=1000;
    private int yMax=750;  
    private double i;
    private double j;
    private int grupo = 0;
    
	public int getSpeed() {
		return speed;
	}

	public void setSpeed(int speed) {
		this.speed = speed;
	}

	public int getxMin() {
		return xMin;
	}

	public void setxMin(int xMin) {
		this.xMin = xMin;
	}

	public int getyMin() {
		return yMin;
	}

	public void setyMin(int yMin) {
		this.yMin = yMin;
	}

	public int getxMax() {
		return xMax;
	}

	public void setxMax(int xMax) {
		this.xMax = xMax;
	}

	public int getyMax() {
		return yMax;
	}

	public void setyMax(int yMax) {
		this.yMax = yMax;
	}

	public Pacman(){
		this.setAppearance(new Circle(new Color(0,0,0,0),30));
		this.setX(210);
		this.setY(570);

		this.setSpeed(100);


	}
	
	private boolean puedemoverarriba(){
		return this.puedeMoverx(this.getX()+15, this.getY());
	}
	
	private boolean puedemoverabajo(){
		return this.puedeMoverx(this.getX()+15, this.getY()+30);
	}
	
	private boolean puedemoverderecha(){
		return this.puedeMovery(this.getX()+30, this.getY()+15);
	}
	
	private boolean puedemoverizquierda(){
		return this.puedeMovery(this.getX(), this.getY()+15);
	}
	
	public void update(DeltaState deltaState) {
		double advanced = this.speed * deltaState.getDelta();
		this.coordinarAnimacion();

		if(this.muere(this.getScene().getGhosts())){
			this.getScene().getMarcador().loose();
			this.getScene().getPacman().setX(210);
			this.getScene().getPacman().setY(570);
			this.getScene().getPskin().setOrientation(3);
			for(Ghost each : this.getScene().getGhosts()){
				each.setTimeToScan(0);
				each.setX(150);
				each.setY(150);
			}
		}
		
		if(deltaState.isKeyBeingHold(Key.D)){
			if(this.puedemoverderecha()){
				
				this.i=1;
				this.j=0;
				this.getScene().getPskin().setOrientation(1);
			}
			
		}
		
		if(deltaState.isKeyBeingHold(Key.A)){
			if(this.puedemoverizquierda()){
				this.i=-1;
				this.j=0;
				this.getScene().getPskin().setOrientation(3);
			}
				
		}
		
		if(deltaState.isKeyBeingHold(Key.S)){
			if(this.puedemoverabajo()){
				this.i=0;
				this.j=1;
				this.getScene().getPskin().setOrientation(2);
			}
		}
		
		if(deltaState.isKeyBeingHold(Key.W)){
			if(this.puedemoverarriba()){
				this.i=0;
				this.j=-1;
				this.getScene().getPskin().setOrientation(0);
			}
		}

		
		this.checkArea(advanced);

		
	}
	
	
	
	
	
	
	
	private void checkArea(double advanced) {
		
		if(this.i== 1&& this.j==0)
			if(this.puedemoverderecha())
				this.move(this.i * advanced, this.j * advanced);
				
		if(this.i==-1&& this.j==0)
			if(this.puedemoverizquierda())
				this.move(this.i * advanced, this.j * advanced);
			
		if(this.i==0&&this.j==1)
			if(this.puedemoverabajo())
				this.move(this.i * advanced, this.j * advanced);
			
		if(this.i==0&&this.j==-1)
			if(this.puedemoverarriba())
				this.move(this.i * advanced, this.j * advanced);
		
	}
	
	public boolean isBlack(int pixel) {
		  int red = (pixel >> 16) & 0xff;
		  int green = (pixel >> 8) & 0xff;
		  int blue = (pixel) & 0xff;
		  return red <= 65  && green <= 65 && blue <= 65;
	}
	
	private boolean puedeMoverx(double xscan, double ybase){
		BufferedImage densityMap = this.getScene().getDensityMap();
		
		int tmpx= (int)xscan -12;
		boolean ret = true;
		for(int i = 0;i<24;i++){
			if(ret){
				ret = !isBlack(densityMap.getRGB(tmpx, (int)ybase));
			}
			tmpx++;
		}
		
		return ret;
		
	}
	
	private boolean puedeMovery(double xbase, double yscan){
		BufferedImage densityMap = this.getScene().getDensityMap();
		
		int tmpy= (int)yscan -12;
		boolean ret = true;
		for(int i = 0;i<24;i++){
			if(ret){
				ret = !isBlack(densityMap.getRGB((int)xbase, tmpy));
			}
			tmpy++;
		}
		
		return ret;
	}

	
	protected boolean muere(ArrayList<Ghost> dots){
		boolean murio = false;
		int i;
		for(i=0;i<dots.size();i++){
			Ghost dot = dots.get(i);
			if(dot.getGrupo() != this.grupo){
				murio = CollisionDetector.INSTANCE.collidesCircleAgainstCircle(
				this.getX(), this.getY(), 
				15, dot.getX(),
				dot.getY(),15);
				}
		}
		
		return murio;
		
	}
	
	public void coordinarAnimacion(){
		this.getScene().getPskin().setX(this.getX()-5);
		this.getScene().getPskin().setY(this.getY()-5);
	}

}
